{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 用户自定义类型\n",
    "\n",
    "一个对象不仅仅存在状态（比如，量的描述），还有行为（比如，运算符）。C++ 提供“类”这一概念用于此目的。一个类就是一个用户自定义类型，由一些内置类型、其他用户自定义类型以及一些函数组成。这些用于定义类的组成部分称为 **成员** （member）。\n",
    "\n",
    "类的结构可以表示为："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "class X {   // 类的名字为 X\n",
    "public:\n",
    "    // 公共成员；\n",
    "    // - 用户接口（可被所有人访问）\n",
    "    // 函数\n",
    "    // 类型\n",
    "    // 数据（通常最好为 private）\n",
    "private:\n",
    "    // 私有成员；\n",
    "    // - 实现细节（仅能被该类的成员访问）\n",
    "    // 函数\n",
    "    // 类型\n",
    "    // 数据\n",
    "};"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "类的数据成员用于定义类对象的表示方法；函数成员提供类对象的运算。\n",
    "\n",
    "类成员默认是私有的，即："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "class X {\n",
    "    int mf(int);\n",
    "    // ...\n",
    "};"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "等价于"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class X {\n",
    "private:\n",
    "    int mf(int);\n",
    "    // ...\n",
    "};"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "类成员的访问使用符号 `object.member`。例如"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class X {\n",
    "public:\n",
    "    int m; // 数据成员\n",
    "    int mf(int v) { // 函数成员\n",
    "        int old = m;\n",
    "        m = v;\n",
    "        return old;\n",
    "    }\n",
    "};"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "X var; // var 为 类型 X 的变量，即 X 的对象"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var.m // 查看 var 的数据成员 m 的初始值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var.m = 7; // 对 var 的数据成员 m 赋值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "int x = var.mf(77); // 调用 var 的成员函数 mf()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x // x 获取的是 var 的数据成员 m 前一个状态值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "77"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "var.m // 获取的是 var 的数据成员 m 当前状态值"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 接口和实现\n",
    "\n",
    "类的声明分为两个部分：接口和实现。公有的接口用标号 `public:` 标识。实现用标号 `private:` 标识。用户只能通过接口间接的访问实现。\n",
    "\n",
    "比如定义如下类："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "class X {\n",
    "    int m; // 数据成员\n",
    "    int mf(int v) { // 函数成员\n",
    "        int old = m;\n",
    "        m = v;\n",
    "        return old;\n",
    "    }\n",
    "};"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用户不能直接访问实现部分：\n",
    "\n",
    "```cpp\n",
    "X x;\n",
    "int y = x.mf() // 错误：mf 是私有的，不能直接访问\n",
    "```\n",
    "\n",
    "用户需要借由公有函数访问实现："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "class X {\n",
    "    int m; // 数据成员\n",
    "    int mf(int v) { // 函数成员\n",
    "        int old = m;\n",
    "        m = v;\n",
    "        return old;\n",
    "    }\n",
    "public:\n",
    "    int f(int i) {\n",
    "        m = i;\n",
    "        return mf(i);\n",
    "    }\n",
    "};"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "X x;\n",
    "int y = x.f(5); // 正确"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 结构体\n",
    "\n",
    "若类只包含数据的话，接口和实现的区分没有太大意义。C++ 使用 **结构** （struct）来描述没有私有实现细节的类。一个结构就是成员默认为公有属性的类："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "struct X {\n",
    "    int m;\n",
    "    // ...\n",
    "};"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "即为："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "class X {\n",
    "public:\n",
    "    int m;\n",
    "    // ...\n",
    "};"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "结构主要用于成员可以取任意值的数据结构。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++11",
   "language": "C++11",
   "name": "python3100jvsc74a57bd0a2954483fe4136a94bd721da8601251ae4c667fedb6adcfe70ff0183b19bacbc"
  },
  "language_info": {
   "codemirror_mode": "text/x-c++src",
   "file_extension": ".cpp",
   "mimetype": "text/x-c++src",
   "name": "c++",
   "version": "11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
